package main

import (
	"runtime"
	"sync"
	"time"

	"gitee.com/Luna-CY/Golang-Project-Template/internal/context"
	"gitee.com/Luna-CY/Golang-Project-Template/internal/context/contextutil"
	"gitee.com/Luna-CY/Golang-Project-Template/internal/interface/dao"
	"gitee.com/Luna-CY/Golang-Project-Template/internal/interface/service"
	"gitee.com/Luna-CY/Golang-Project-Template/internal/logger"
	"gitee.com/Luna-CY/Golang-Project-Template/internal/util/timer"
	"gitee.com/Luna-CY/Golang-Project-Template/model"
	"github.com/spf13/cobra"
)

func NewWorkerSendSmsCommand() *cobra.Command {
	var command = &cobra.Command{
		Use:   "send-sms",
		Short: "发送短信",
		Run: func(cmd *cobra.Command, args []string) {
			defer func() {
				cmd.Println("发送短信任务已停止")
			}()

			cmd.Println("发送短信任务已启动")

			var ctx = contextutil.NewContextWithStandard(cmd.Context())

			var smsService = NewSmsService()

			// 启动处理器

			var wg = sync.WaitGroup{}
			wg.Add(runtime.NumCPU())

			var ch = make(chan *model.SystemSmsLog, runtime.NumCPU()*10)
			for range runtime.NumCPU() {
				go smsSendProcessor(ctx, &wg, ch)
			}

			timer.NewMinuteTicker(ctx, func(ctx context.Context, ticker *time.Ticker, now time.Time) {
				cmd.Printf("运行时间: %v\n", now)

				var page = 1
				for {
					_, data, err := smsService.ListSmsLogByCondition(ctx, page, 100, dao.SystemSmsLogOptionWithSendType(model.SystemSmsLogSendTypeTime), dao.SystemSmsLogOptionWithSendTimeEqualOrLessThan(now.Unix()))
					if nil != err {
						logger.SugarLogger(logger.WithRequestId(ctx), logger.WithStack()).Errorf("CMC_ND.NWSSC_ND.464525 查询短信日志失败，错误信息为 %q", err.Error())

						break
					}

					for _, item := range data {
						ch <- item
					}

					if 100 != len(data) {
						break
					}

					page += 1
				}
			})

			close(ch)
			wg.Wait()
		},
	}

	return command
}

func smsSendProcessor(ctx context.Context, wg *sync.WaitGroup, ch <-chan *model.SystemSmsLog) {
	defer wg.Done()

	var smsService = NewSmsService()

	for smsLog := range ch {
		if err := smsService.SendTimeTo(ctx, smsLog); nil != err {
			logger.SugarLogger(logger.WithRequestId(ctx), logger.WithStack()).Errorf("CMC_ND.NWSSC_ND.814907 发送短信失败，错误信息为 %q", err.Error())

			if err := smsService.UpdateLog(ctx, smsLog, service.SystemSmsLogFieldWithStatus(model.SystemSmsLogStatusFailed), service.SystemSmsLogFieldWithFailedReason(err.Error())); nil != err {
				logger.SugarLogger(logger.WithRequestId(ctx), logger.WithStack()).Errorf("CMC_ND.NWSSC_ND.844911 更新短信日志失败，错误信息为 %q", err.Error())
			}
		}
	}
}
